<!-- pages/index/index.vue -->
<template>
	<view class="container">
		<button @click="toggleStream">{{ isStreaming ? '停止' : '开始' }}流式请求</button>
		<scroll-view scroll-y class="output">
			<view class="" style="padding: 20rpx;">
				{{ output }}
			</view>
		</scroll-view>
		
		<image  v-if="getphotoUrl != ''" :src="getphotoUrl" mode="widthFix" style="width: ;"></image>
	</view>
</template>

<script>
	// 测试用 基础流式输出
	// 模拟流式接口地址（实际使用时替换为真实接口）
	// const MOCK_STREAM_API = 'https://mock-api.liuxianyu.cn/mock/stream'
	// const MOCK_STREAM_API = 'https://chain.artigit.com/gpt/api/PrivateSession/askstream'
	const reqUrl = "http://192.168.1.30:9000"
	const MOCK_STREAM_API = reqUrl + '/api/TakePhoto/tpcreate?openid=12151515'

	export default {
		data() {
			return {
				output: '',
				isStreaming: false,
				controller: null, // 用于存储AbortController实例
				reader: null, // 用于存储ReadableStream的reader
				
				getphotoUrl:"",
			}
		},
		methods: {
			async toggleStream() {
				if (this.isStreaming) {
					this.stopStream()
				} else {
					await this.startStream()
				}
			},

			async startStream() {
				try {
					// 初始化状态
					this.isStreaming = true
					// this.output = '▶️ 开始连接...\n'

					// 创建中止控制器（关键点1：AbortController）
					this.controller = new AbortController()

					// 发起fetch请求（关键点2：signal参数）
					const response = await fetch(MOCK_STREAM_API, {
						method: 'GET',
						headers: {
							'Content-Type': 'application/json'
						},
						// body: JSON.stringify({
						// 	id: "oZ-tj49NGxoxqML4cmCpOy25uGU0",
						// 	 question: "你好",
						// 	 sessionid: "",
						// 	 prepare:[],
							 
						// }),
						// method: 'POST',
						// headers: {
						// 	'Content-Type': 'application/json'
						// },
						// body: JSON.stringify({
						// 	id: "oZ-tj49NGxoxqML4cmCpOy25uGU0",
						// 	 question: "你好",
						// 	 sessionid: "",
						// 	 prepare:[],
							 
						// }),
						signal: this.controller.signal // 绑定中止信号
					})

					// 处理响应错误
					if (!response.ok) {
						throw new Error(`HTTP错误! 状态码: ${response.status}`)
					}

					// 获取可读流（关键点3：ReadableStream）
					const reader = response.body.getReader()
					this.reader = reader
					const decoder = new TextDecoder()

					// 持续读取流数据（关键点4：循环读取）
					while (true) {
						// 读取数据块（关键点5：done标识）
						const {
							done,
							value
						} = await reader.read()

						// 如果流结束则退出循环
						if (done) {
							// this.output += '\n\n✅ 流式传输完成'
							break
						}

						// 解码并处理数据（可在此处处理业务逻辑）
						const textChunk = decoder.decode(value, {
							stream: true
						})
						this.output += textChunk
						console.log(this.output)
						
						// 强制更新视图（解决部分环境渲染问题）
						this.$forceUpdate()
					}
				} catch (error) {
					// 处理中止请求的特殊情况
					if (error.name === 'AbortError') {
						this.output += '\n\n⏹️ 用户主动中止'
					} else {
						console.error('请求失败:', error)
						this.output += `\n\n❌ 错误: ${error.message}`
					}
				} finally {
					// 清理资源
					this.isStreaming = false
					this.controller = null
					this.reader = null
				}
			},

			stopStream() {
				if (this.controller) {
					// 中止fetch请求
					this.controller.abort()
				}
				if (this.reader) {
					// 释放reader资源
					this.reader.cancel()
				}
			},
			
			// http://192.168.1.30:9000/api/TakePhoto/getphoto
			
			getphoto(){
				
				uni.request({
					url: reqUrl + "/api/TakePhoto/getphoto",
					success: (res) => {
								console.log(res);
									console.log(res.data);
									console.log(res.data.code);
						if(res.data.code == 200){
						
							that.num = res.data.data;
						}
					 }
				})
			},
		},

		beforeDestroy() {
			// 组件销毁时自动停止请求
			this.stopStream()
		}
	}
</script>

<style>
	.container {
		padding: 20px;
		width: 90vw;
	}

	button {
		background-color: #007AFF;
		color: white;
		padding: 12px 24px;
		border-radius: 8px;
		margin-bottom: 20px;
	}

	.output {
		height: 60vh;
		width: 100%;
		
	
		background-color: #f5f5f5;
		border-radius: 8px;
		font-family: monospace;
		white-space: pre-wrap;
		
	}
</style>